(in-package "ACL2")
(include-book "grid")
(include-book "rule-creator")
(include-book "cell")

;;;The world is a big structure where we store stuff that multiple modules might 
;;;care about. This file contains methods for generating the start world and
;;;updating a field in the world
(defstructure cell-world
    (grid (:assert (grid? grid)))
    (rules (:assert (ruleset? rules)))
    (framerate (:assert (rationalp framerate)))
    (changeset (:assert (cell-listp changeset)))
    (should-terminate)
    (num-commands-read)
    (gen-num))

(defconst *default-framerate* 0)

;;generate the start world.
(defun construct-world (rules)
    (let*  ((ruletype (ruleset-rule-type rules))
            (empty-grid (cond
                          ((equal ruletype "lifelike") 
                              (empty-lifelike-grid))
                          ((equal ruletype "elementary")
                              (empty-elementary-grid))
                          (t "error")))
            (no-changes nil))
        (cell-world empty-grid rules *default-framerate* no-changes nil 0 0)))

;;return a new world copied from wld, save that the grid is set to the
;;grid parameter
(defun set-world-grid (wld grid)
    (cell-world grid (cell-world-rules wld) (cell-world-framerate wld) 
        (cell-world-changeset wld) (cell-world-should-terminate wld)
        (cell-world-num-commands-read wld) (cell-world-gen-num wld)))

;;return a new world copied from wld, save that the framerate is set to the 
;;framerate parameter
(defun set-world-framerate (wld framerate)
  (cell-world (cell-world-grid wld) (cell-world-rules wld)
    framerate (cell-world-changeset wld) 
    (cell-world-should-terminate wld) (cell-world-num-commands-read wld)
    (cell-world-gen-num wld)))

;;return a new world copied from wld, save that the rules is set to the 
;;rules parameter
(defun set-world-rules (wld rules)
  (cell-world (cell-world-grid wld) rules
    (cell-world-framerate wld) (cell-world-changeset wld) 
    (cell-world-should-terminate wld) (cell-world-num-commands-read wld)
    (cell-world-gen-num wld)))

;;return a new world copied from wld, save that the changeset is set to the 
;;changeset parameter
(defun set-world-changeset (wld changeset)
  (cell-world (cell-world-grid wld) (cell-world-rules wld)
   (cell-world-framerate wld) changeset
   (cell-world-should-terminate wld) (cell-world-num-commands-read wld)
   (cell-world-gen-num wld)))

;;return a new world copied from wld, save that the number of commands read
;;is set to the num-commadns parameter
(defun set-num-commands-read (wld num-commands)
  (cell-world (cell-world-grid wld) (cell-world-rules wld)
   (cell-world-framerate wld) (cell-world-changeset wld) 
   (cell-world-should-terminate wld) num-commands (cell-world-gen-num wld)))

;;return a new world with the number of commands read increased by one
(defun increment-num-commands-read (wld)
 (set-num-commands-read wld  (1+ (cell-world-num-commands-read wld))))

;;return a new world copied from wld, save that the generation number is set to the 
;;gen-num parameter
(defun set-world-gen-num (wld gen-num)
  (cell-world (cell-world-grid wld) (cell-world-rules wld)
   (cell-world-framerate wld) (cell-world-changeset wld) 
   (cell-world-should-terminate wld) (cell-world-num-commands-read wld)
   gen-num))

;;return a new world with the generation number increased by 1
(defun increment-world-gen-num (wld)
  (set-world-gen-num wld (1+ (cell-world-gen-num wld))))